package com.jsh.erp.service.functions;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSONObject;
import com.jsh.erp.constants.BusinessConstants;
import com.jsh.erp.constants.ExceptionConstants;
import com.jsh.erp.datasource.entities.Functions;
import com.jsh.erp.datasource.entities.FunctionsExample;
import com.jsh.erp.datasource.entities.User;
import com.jsh.erp.datasource.mappers.FunctionsMapper;
import com.jsh.erp.datasource.mappers.FunctionsMapperEx;
import com.jsh.erp.exception.BusinessRunTimeException;
import com.jsh.erp.exception.JshException;
import com.jsh.erp.service.log.LogService;
import com.jsh.erp.service.user.UserService;
import com.jsh.erp.utils.StringUtil;

@Service
public class FunctionsService {
	private Logger logger = LoggerFactory.getLogger(FunctionsService.class);

	@Resource
	private FunctionsMapper functionsMapper;

	@Resource
	private FunctionsMapperEx functionsMapperEx;
	@Resource
	private UserService userService;
	@Resource
	private LogService logService;

	private static volatile List<Functions> nodes;

	/**
	 * 获取所有的节点，并且按照树形结构进行组合
	 * @author yzh
	 * @date 2020年6月30日
	 *  
	 * @return
	 */
	public List<Functions> getAllNodes() {
		if (nodes == null) {
			synchronized (FunctionsService.class) {
				if (nodes == null) {
					FunctionsExample functionsExample = new FunctionsExample();
					functionsExample.createCriteria().andDeleteFlagNotEqualTo("1");
					List<Functions> selectByExample = functionsMapper.selectByExample(functionsExample);
					nodes = new ArrayList<Functions>();
					Functions.sortChildren(nodes, selectByExample, "0");
				}
			}
		}
		return nodes;

	}

	/**
	 * 清空node信息
	 * @author yzh
	 * @date 2020年6月30日
	 *
	 */
	public void clearNode() {
		synchronized (FunctionsService.class) {
			nodes = null;
		}
	}

	public Functions getFunctions(long id) throws Exception {
		Functions result = null;
		try {
			result = functionsMapper.selectByPrimaryKey(id);
		} catch (Exception e) {
			JshException.readFail(logger, e);
		}
		return result;
	}

	public List<Functions> getFunctions() throws Exception {
		FunctionsExample example = new FunctionsExample();
		example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
		List<Functions> list = null;
		try {
			list = functionsMapper.selectByExample(example);
		} catch (Exception e) {
			JshException.readFail(logger, e);
		}
		return list;
	}

	public List<Functions> select(String name, String type, int offset, int rows) throws Exception {
		List<Functions> list = null;
		try {
			list = functionsMapperEx.selectByConditionFunctions(name, type, offset, rows);
		} catch (Exception e) {
			JshException.readFail(logger, e);
		}
		return list;
	}

	public Long countFunctions(String name, String type) throws Exception {
		Long result = null;
		try {
			result = functionsMapperEx.countsByFunctions(name, type);
		} catch (Exception e) {
			JshException.readFail(logger, e);
		}
		return result;
	}

	@Transactional(value = "transactionManager", rollbackFor = Exception.class)
	public int insertFunctions(String beanJson, HttpServletRequest request) throws Exception {
		Functions depot = JSONObject.parseObject(beanJson, Functions.class);
		int result = 0;
		try {
			result = functionsMapper.insertSelective(depot);
		} catch (Exception e) {
			JshException.writeFail(logger, e);
		}
		return result;
	}

	@Transactional(value = "transactionManager", rollbackFor = Exception.class)
	public int updateFunctions(String beanJson, Long id) throws Exception {
		Functions depot = JSONObject.parseObject(beanJson, Functions.class);
		depot.setId(id);
		int result = 0;
		try {
			result = functionsMapper.updateByPrimaryKeySelective(depot);
		} catch (Exception e) {
			JshException.writeFail(logger, e);
		}
		return result;
	}

	@Transactional(value = "transactionManager", rollbackFor = Exception.class)
	public int deleteFunctions(Long id) throws Exception {
		int result = 0;
		try {
			result = functionsMapper.deleteByPrimaryKey(id);
		} catch (Exception e) {
			JshException.writeFail(logger, e);
		}
		return result;
	}

	@Transactional(value = "transactionManager", rollbackFor = Exception.class)
	public int batchDeleteFunctions(String ids) throws Exception {
		List<Long> idList = StringUtil.strToLongList(ids);
		FunctionsExample example = new FunctionsExample();
		example.createCriteria().andIdIn(idList);
		int result = 0;
		try {
			result = functionsMapper.deleteByExample(example);
		} catch (Exception e) {
			JshException.writeFail(logger, e);
		}
		return result;
	}

	public int checkIsNameExist(Long id, String name) throws Exception {
		FunctionsExample example = new FunctionsExample();
		example.createCriteria().andIdNotEqualTo(id).andNameEqualTo(name)
				.andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
		List<Functions> list = null;
		try {
			list = functionsMapper.selectByExample(example);
		} catch (Exception e) {
			JshException.readFail(logger, e);
		}
		return list == null ? 0 : list.size();
	}

	public List<Functions> getRoleFunctions(String pNumber) throws Exception {
		FunctionsExample example = new FunctionsExample();
		example.createCriteria().andEnabledEqualTo(true).andPnumberEqualTo(pNumber)
				.andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
		example.setOrderByClause("Sort");
		List<Functions> list = null;
		try {
			list = functionsMapper.selectByExample(example);
		} catch (Exception e) {
			JshException.readFail(logger, e);
		}
		return list;
	}

	public List<Functions> findRoleFunctions(String pnumber) throws Exception {
		FunctionsExample example = new FunctionsExample();
		example.createCriteria().andEnabledEqualTo(true).andPnumberEqualTo(pnumber)
				.andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
		example.setOrderByClause("Sort");
		List<Functions> list = null;
		try {
			list = functionsMapper.selectByExample(example);
		} catch (Exception e) {
			JshException.readFail(logger, e);
		}
		return list;
	}

	public List<Functions> findByIds(String functionsIds) throws Exception {
		List<Long> idList = StringUtil.strToLongList(functionsIds);
		FunctionsExample example = new FunctionsExample();
		example.createCriteria().andEnabledEqualTo(true).andIdIn(idList)
				.andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
		example.setOrderByClause("Sort asc");
		List<Functions> list = null;
		try {
			list = functionsMapper.selectByExample(example);
		} catch (Exception e) {
			JshException.readFail(logger, e);
		}
		return list;
	}

	@Transactional(value = "transactionManager", rollbackFor = Exception.class)
	public int batchDeleteFunctionsByIds(String ids) throws Exception {
		/**
		 * 对于系统管理下的菜单，限制不能随意删除，否则会带来极大问题
		 * */
		logService.insertLog(BusinessConstants.LOG_INTERFACE_NAME_FUNCTIONS,
				new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_DELETE).append(ids).toString(),
				((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
		User userInfo = userService.getCurrentUser();
		String[] idArray = ids.split(",");
		// 查询此次删除是否包含系统管理下的菜单
		List<Functions> systemManageMentFunctions = functionsMapperEx.selectSystemManageMentFunctionsByIds(idArray);
		if (systemManageMentFunctions != null && systemManageMentFunctions.size() > 0) {
			logger.error("异常码[{}],异常提示[{}],参数,ids[{}]",
					ExceptionConstants.FUNCTIONS_DELETE_INCLUE_SYS_MANAGE_NOT_ALLOWED_CODE,
					ExceptionConstants.FUNCTIONS_DELETE_INCLUE_SYS_MANAGE_NOT_ALLOWED_MSG, ids);
			throw new BusinessRunTimeException(ExceptionConstants.FUNCTIONS_DELETE_INCLUE_SYS_MANAGE_NOT_ALLOWED_CODE,
					ExceptionConstants.FUNCTIONS_DELETE_INCLUE_SYS_MANAGE_NOT_ALLOWED_MSG);
		}
		int result = 0;
		try {
			result = functionsMapperEx.batchDeleteFunctionsByIds(new Date(), userInfo == null ? null : userInfo.getId(),
					idArray);
		} catch (Exception e) {
			JshException.writeFail(logger, e);
		}
		return result;
	}

}
